home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / utils / gemfxm15.lzh / MEMFIND.LZH / MEMFIND.C next >
C/C++ Source or Header  |  1990-05-27  |  13KB  |  339 lines

  1.  
  2. /**************************************************************************
  3.  *
  4.  * MEMFIND.C - An example program for AESFAST which uses just dialogs.
  5.  *
  6.  *  Public Domain example program by Ian Lepore.
  7.  *
  8.  *  This is distributed as an example of how to write a simple program using
  9.  *  my AESFAST public domain GEM bindings.  This example uses a few of
  10.  *  the nifty utilities from AESFAST, but it's pretty much straightforward
  11.  *  dialog-handling code.
  12.  *
  13.  *  This beast may be marginally useful beyond its value as an example.
  14.  *  It will find and report on the 5 biggest blocks of free memory in 
  15.  *  the system, giving a somewhat more acurate view than programs which
  16.  *  report only the largest free block.
  17.  *
  18.  *  This code is pretty heavily commented.  Please excuse me if some of 
  19.  *  the comments seem obvious, but I figure the audience for this will 
  20.  *  include both beginning C programmers, and old-timers who just need to
  21.  *  see how my bindings work as opposed to other bindings.
  22.  *
  23.  *************************************************************************/
  24.  
  25. #include <gemfast.h>
  26. #include <osbind.h>
  27. #include "memfind.h"
  28.  
  29. #ifndef TRUE
  30. #define TRUE  1
  31. #define FALSE 0
  32. #endif
  33.  
  34. #define NO_RSRC   -2783        /* a random number */
  35.  
  36. /**************************************************************************
  37.  *
  38.  * global vars
  39.  *
  40.  *************************************************************************/
  41.  
  42. typedef struct {
  43.         char *pmem;
  44.         long lmem;
  45.         int  objlink;
  46.         char displaystr[25];
  47.         } MEM_BLOCK;
  48.  
  49. #define NUM_BLOCKS 5
  50.  
  51. MEM_BLOCK mem_ctl[NUM_BLOCKS];
  52.  
  53. OBJECT    *maintree;
  54.  
  55. char map_template[] = "$%06lx    %4dk";    /* template for printf() */
  56.  
  57. char no_rsrc_alert[] = "[3][ | Can't open/load RSC file! | ][ Fatal ]";
  58.  
  59. /**************************************************************************
  60.  *
  61.  * prg_exit - Cleanup and terminate.
  62.  *  If the exit code is our magic number NO_RSRC (indicating that we're
  63.  *  exiting because the resource load failed), we skip the rsrc_free call.
  64.  *
  65.  *************************************************************************/
  66.  
  67. void
  68. prg_exit(code)
  69.         int code;
  70. {
  71.         if (code != NO_RSRC) {
  72.                 rsrc_free();
  73.         }
  74.  
  75.         appl_exit();
  76.         Pterm(code);
  77. }
  78.  
  79. /**************************************************************************
  80.  *
  81.  * prg_init.
  82.  *
  83.  *  This routine does mundance AES init stuff, and makes the connections
  84.  *  between the string objects in the resource tree and the elements in
  85.  *  our memory control array.
  86.  *
  87.  *  The connections concept is based upon accessing arrays of strings in
  88.  *  a dialog box without knowing the actual object indicies (names) of
  89.  *  the string objects.  (Some discussion of this can also be found in 
  90.  *  the MINICOLR accessory example code).  I'll be the first to admit
  91.  *  that this technique is overkill for this little program, since only
  92.  *  five text strings are involved.  On the other hand, you can increase
  93.  *  the number of displayed memory fragments simply by going into the 
  94.  *  resource file and making a few more copies of the display strings, 
  95.  *  then coming into this source code and increasing NUM_BLOCKS to match
  96.  *  the new number of display strings in the resource file.  No other 
  97.  *  changes are necessary, and *that's* something you can't say about
  98.  *  'normal' GEM coding techniques.
  99.  *
  100.  *   What this technique really does is isolate the location of the objects
  101.  *   in the RSC file from the program code.  Thus, a hacker-type can munge
  102.  *   up the resource file and the program will still run correctly, even
  103.  *   if objects are added, deleted, moved, or sorted.
  104.  *
  105.  *   In this implementation, I've set an 'extended object type' on each
  106.  *   of the display string objects, using my resource editor.  I chose
  107.  *   a value of '1' for the extended type, but this is completely 
  108.  *   arbitrary.
  109.  *
  110.  *   Just for grins, I'll list here the code I would have used if I hadn't
  111.  *   implemented the location-independant connections concept.  First, I'll
  112.  *   explain my standard for naming objects...
  113.  *       nnnnttxx
  114.  *       ||||||++--- 2 char arbitrary id (my object name)
  115.  *       ||||++----- object type (see list below)
  116.  *       ++++------- name of the tree holding the object
  117.  *     Object types for naming standards are:
  118.  *        BX  - Button (eXit)
  119.  *        BR  - Button (Radio) (also used for radio boxchars)
  120.  *        ST  - STring
  121.  *        TX  - TeXt (display only)
  122.  *        TE  - Text (Editable)
  123.  *        PB  - Parent Box (usually invisible, parent for radio buttons)
  124.  *        TREE- Special-case name, indicates a root (R_TREE) objct.
  125.  *     Thus, using this standard, you might have:
  126.  *        MAINBXOK - Exit button 'OK' in main dialog box.
  127.  *        DEVSBRDA - Radio Button for drive A in device selection dialog.
  128.  *        MAINSTM1 - Display string M1 in main dialog.
  129.  *
  130.  *   Anyway, enough standards.  You don't have to use my standard, but
  131.  *   I'd advise you to use *some* kind of naming standard that ties object
  132.  *   names to the trees they live in, if you want to maintain your sanity.
  133.  *
  134.  *   So, IF I had done this program in the 'normal' way, the loop below
  135.  *   which does the 'connections' works would be replaced by the following:
  136.  *
  137.  *      rsc_sstrings(maintree,
  138.  *                      MAINSTM1,mem_ctl[0].displaystr,
  139.  *                      MAINSTM2,mem_ctl[1].displaystr,
  140.  *                      MAINSTM3,mem_ctl[2].displaystr,
  141.  *                      MAINSTM4,mem_ctl[3].displaystr,
  142.  *                      MAINSTM5,mem_ctl[4].displaystr,
  143.  *                      -1);
  144.  *
  145.  *   The rsc_sstrings routine is an AESFAST library routine that sets the
  146.  *   ob_spec pointers for 1-n strings within a dialog tree.
  147.  *************************************************************************/
  148.  
  149. void
  150. prg_init()
  151. {
  152.         int                dmy;
  153.         register int       objcounter;
  154.         register int       strcounter;
  155.         register OBJECT    *pobj;
  156.         register MEM_BLOCK *pblock;
  157.         
  158. /*
  159.  * call AES init, then try to load the resource file.  if the RSC load
  160.  * fails, go whine at the user and exit.
  161.  */
  162.  
  163.         appl_init();
  164.         
  165.         if (!rsrc_load("MEMFIND.RSC")) {
  166.                 form_alert(no_rsrc_alert);
  167.                 prg_exit(NO_RSRC);
  168.         }
  169.  
  170. /*
  171.  * get the address of the dialog tree
  172.  */
  173.      
  174.         rsrc_gaddr(R_TREE, MAINTREE, &maintree);
  175.    
  176. /*
  177.  * connect up the links between the memory control structures and the
  178.  * object structures... (see notes above).
  179.  *
  180.  * go through the object tree, and each time we encounter an object
  181.  * with the right extended object type, connect that object's ob_spec
  182.  * pointer to the display string in the memory control structure, and
  183.  * make note of the object's index in the objlink field of the memory
  184.  * control structure.  normally, only the ob_spec link would be made,
  185.  * but for our application we need to be able to set an object's flags
  186.  * to HIDETREE if we discover an empty block in the memory control struct.
  187.  *
  188.  * the loop control here will stop if we run out of memory control blocks
  189.  * or if we run out of objects in the tree.  this means that if someone
  190.  * munges up the resource file and removes some of our string objects,
  191.  * then some memory blocks won't be displayed, but at least nothing dies.
  192.  */     
  193.         objcounter = strcounter = 0;
  194.         do      {
  195.                 pobj = &maintree[objcounter];
  196.                 if (1 == (pobj->ob_type >> 8)) {
  197.                         pblock = &mem_ctl[strcounter];
  198.                         pobj->ob_spec  = (long)pblock->displaystr;
  199.                         pblock->objlink = objcounter;
  200.                         strcounter++;
  201.                 }
  202.                 objcounter++;
  203.         } while ( (strcounter < NUM_BLOCKS) &&
  204.                   (!(pobj->ob_flags & LASTOB)) );
  205.  
  206. /* 
  207.  * init all done, change the mouse from a busy-bee to an arrow.
  208.  */
  209.         graf_mouse(ARROW, 0L);
  210. }
  211.  
  212. /************************************************************